package com.sz.biz.trade.ord.service.impl;

import com.google.common.collect.Lists;
import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.trade.ord.entity.TrdOrder;
import com.sz.biz.trade.ord.entity.TrdOrderFileRel;
import com.sz.biz.common.AbstractVersionEntityService;
import com.sz.biz.trade.ord.service.TrdOrderFileRelService;
import com.sz.biz.trade.ord.service.TrdOrderService;
import com.sz.biz.trade.ord.dto.TrdOrderFileRelDto;
import com.sz.biz.logistics.constants.ErrorCodes;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.entity.SysDict;
import com.sz.common.core.system.entity.SysFile;
import com.sz.common.core.system.service.SysDictService;
import com.sz.common.core.system.service.SysFileService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Function: 贸易订单文件服务 <br>
 * Author: jifeixing <br>
 * Date: 2017-08-11 14:09:00
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class TrdOrderFileRelServiceImpl extends AbstractVersionEntityService implements TrdOrderFileRelService {
    @Autowired
    private TrdOrderService trdOrderService;
    @Autowired
    private SysDictService dictService;
    @Autowired
    private SysFileService sysFileService;



    @Override
    protected String getMapperNamespace() {
        return "TrdOrderFileRelMapper";
    }

    /**
     * 订单文件保存
     * @param trdOrderFileRel
     */
    @Override
    public void save(TrdOrderFileRel trdOrderFileRel) {
        dao.save(getSqlName("insertSelective"), trdOrderFileRel);
    }

    /**
     * 增加附件
     * 订单是否存在
     * 文件的名称唯一性校验
     * 文件的状态需要和订单的状态一致
     *
     * @param trdOrderFileRelDto
     */
    @Override
    public TrdOrderFileRel addOrderFileDto(TrdOrderFileRelDto trdOrderFileRelDto) {
        TrdOrder trdOrder = trdOrderService.findByOrderNo(trdOrderFileRelDto.getOrderNo());
        if (null == trdOrder) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ORD_ORDER_NOT_EXIST);
        }
        TrdOrderFileRel file = new TrdOrderFileRel();
        //检查文件名是否唯一
        if (checkUniqueName(trdOrderFileRelDto.getOrderNo(), trdOrderFileRelDto.getName())) {
            EntityUtils.copyPropertiesIgnoreNull(trdOrderFileRelDto, file);
            file.setCreateUserId(PrincipalUtils.getAccountId());
            file.setLastUpdateUserId(PrincipalUtils.getAccountId());
            file.setOrderStatus(trdOrder.getOrderStatus().toString());
            dao.save(getSqlName("insertSelective"), file);
        } else {
            throw Exceptions.bizException(ErrorCodes.ERROR_ORD_ORDER_FILE_NAME_EXIST);
        }
        return file;
    }


    /**
     * 订单文件保存
     * @param trdOrderFileRel
     */
    @Override
    public void update(TrdOrderFileRel trdOrderFileRel){
        dao.save(getSqlName("updateByPrimaryKeySelective"), trdOrderFileRel);
    }

    /**
     * 订单附件
     * @param orderNo
     * @return
     */
    @Override
    public List<TrdOrderFileRel> findByOrderNo(String orderNo) {
        return dao.findForList(getSqlName("findByOrderNo"), orderNo, TrdOrderFileRel.class);
    }

    /**
     * 删除订单附件
     * @param orderNo
     */
    @Override
    public void deleteByOrderNo(String orderNo) {
        dao.update(getSqlName("deleteByOrderNo"), orderNo);
    }

    /**
     * return false ; 表示，有重复名字.
     * return true ; 表示无重复名字
     *
     * @param orderNo
     * @param fileName
     * @return
     */
    @Override
    public Boolean checkUniqueName(String orderNo, String fileName) {
        ParamData pd = new ParamData();
        pd.put("orderNo", orderNo);
        pd.put("fileName", fileName);
        TrdOrderFileRel trdOrderFileRel = (TrdOrderFileRel) dao.findForObject(getSqlName("getByOrderAndFileName"), pd);
        if (null != trdOrderFileRel) {
            return false;
        }
        return true;
    }


    @Override
    public List<TrdOrderFileRel> saveOrdFiles(String orderNo, String trdOrderStatus, List<TrdOrderFileRel> trdOrderFileRels) {
        List<TrdOrderFileRel> fileList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(trdOrderFileRels)) {
            checkUniqueName(trdOrderFileRels);
            trdOrderFileRels.forEach(trdOrderFileRel -> {
                TrdOrderFileRel file = new TrdOrderFileRel();
                EntityUtils.copyPropertiesIgnoreNull(trdOrderFileRel, file);
                file.setOrderNo(orderNo);
                file.setCreateUserId(PrincipalUtils.getAccountId());
                file.setLastUpdateUserId(PrincipalUtils.getAccountId());
                file.setOrderStatus(trdOrderStatus);
                fileList.add(file);
            });
            //保存到数据库
            dao.batchInsert(getSqlName("insertSelective"), fileList);
            //保存操作日志
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("ADD_TRD_ORDER_FILE", fileList);
            PrincipalLogUtils.addOperationLog(ModuleNames.TRD, ModuleNames.TRD_ORDER_FILE, UserActions.ADD, "添加贸易订单附件", dataBackup);
        }
        return fileList;
    }

    /**
     * return false ; 表示，有重复名字.
     * return true ; 表示无重复名字
     *
     * @param trdOrderFileRels
     * @return
     */
    @Override
    public Boolean checkUniqueName(List<TrdOrderFileRel> trdOrderFileRels){
        if (CollectionUtils.isNotEmpty(trdOrderFileRels)) {
            Map<String, Object> map = new HashedMap();
            for (TrdOrderFileRel trdOrderFileRel :
                    trdOrderFileRels) {
                if (map.containsKey(trdOrderFileRel.getName())) {
                    //map中已经有这个filename了，表示名字重复了
                    throw Exceptions.bizException(ErrorCodes.ERROR_ORD_ORDER_FILE_NAME_EXIST);
                }
                map.put(trdOrderFileRel.getName(), trdOrderFileRel);
            }
        }
        return true;
    }
    /**
     *
     * @param id
     * @return
     */
    @Override
    public TrdOrderFileRel findById(Integer id) {
        ParamData pd = new ParamData();
        pd.put("id", id);
        TrdOrderFileRel trdOrderFileRel = (TrdOrderFileRel) dao.findForObject(getSqlName("findById"), pd);
        return trdOrderFileRel;
    }

    /**
     * 删除附件
     * <p>
     * 附加是否存在
     * 订单是否存在，
     * 附件和订单是否匹配
     * 该状态是否可以删掉（运营系统的人可以删除任何状态的附件，客户系统的人只可以删除当前状态的文件）
     * <p>
     * 客户系统的操作，在已经提交状态下可以删除草稿状态的附件
     *
     * @param orderNo
     * @param id
     */
    @Override
    public void deleteTrdOrderFile(String orderNo, Integer id) {
        TrdOrderFileRel trdOrderFileRel = findById(id);
        TrdOrderFileRelDto  trdOrderFileRelDto=new TrdOrderFileRelDto();
        if (null == trdOrderFileRel) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ORD_ORDER_FILE_NOT_EXIST);
        }
        TrdOrder trdOrder = trdOrderService.findByOrderNo(orderNo);
        if (null == trdOrder) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ORD_ORDER_NOT_EXIST);
        }
        if (!trdOrderFileRel.getOrderNo().equals(trdOrder.getOrderNo())) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ORD_ORDER_FILE_NOT_EXIST);
        }
        EntityUtils.copyPropertiesIgnoreNull(trdOrderFileRel, trdOrderFileRelDto);
        //附件的删除
        dao.delete(getSqlName("deleteByPrimaryKey"), id);
        // 日志
//        Map<String, Object> dataBackup = new HashMap<>();
//        dataBackup.put("UPDATE_TRD_ORDER_FILE", id);
//        PrincipalLogUtils.addOperationLog(ModuleNames.TRD, ModuleNames.TRD_ORDER_FILE, UserActions.DELETE, "删除订单附件", dataBackup);
//        Integer accountId = PrincipalUtils.getAccountId();
//        Integer domainId = PrincipalUtils.getDomainId();
//        bizOperationLogService.saveOrderFileUpdateLog(trdOrder.getId(), trdOrder.getOrderStatus(), UserActions.DELETE, trdOrderFileRelDto,accountId,domainId);
    }

    /**
     * 分页获取某个订单下的附件列表
     *
     * @param params
     * @return
     */
    @Override
    public ResultDto findFileDtoPages(QueryParams params) {
        ParamData pd = convertQueryParams(params);
        List<TrdOrderFileRelDto> trdOrderFileRelDtos = Lists.newArrayList();
        List<TrdOrderFileRel> trdOrderFileRels = dao.findForList(getSqlName("findListPage"), pd, TrdOrderFileRel.class);
        if (CollectionUtils.isNotEmpty(trdOrderFileRels)) {
            for(TrdOrderFileRel trdOrderFileRel:trdOrderFileRels){
                TrdOrderFileRelDto trdOrderFileRelDto=new TrdOrderFileRelDto();
                EntityUtils.copyPropertiesIgnoreNull(trdOrderFileRel, trdOrderFileRelDto);
                if(trdOrderFileRel.getFileId()!=null){
                    SysFile file= sysFileService.getFileInfo(trdOrderFileRel.getFileId());
                    trdOrderFileRelDto.setFileUrl(file.getFileLocation());
                }
                trdOrderFileRelDtos.add(trdOrderFileRelDto);
            }
        }
        List<String> fileIds = Lists.newArrayList();
        trdOrderFileRelDtos.forEach(trdOrderFileRel -> {
            fileIds.add(trdOrderFileRel.getFileId());
        });
        //获取数据库的所有文件配置
        List<SysDict> dictList = dictService.queryOrderFileTypes(CommCodes.TRD_ORDER_FILE_TYPE_CATALOG, null);
        Map<String, SysDict> dictMap = new HashedMap();
        if (CollectionUtils.isNotEmpty(dictList)) {
            dictList.forEach(sysDict -> {
                dictMap.put(sysDict.getCode(), sysDict);
            });
        }

        Map<String, SysFile> fileMap = new HashedMap();
        //获取文件信息
        if (CollectionUtils.isNotEmpty(fileIds)) {
            List<SysFile> files = sysFileService.getFileInfos(fileIds);
            if (CollectionUtils.isNotEmpty(files)) {
                files.forEach(file -> {
                    fileMap.put(file.getFileId(), file);
                });
            }
        }
        if(CollectionUtils.isNotEmpty(trdOrderFileRelDtos)){
            for(TrdOrderFileRelDto trdOrderFileRelDto:trdOrderFileRelDtos){
                trdOrderFileRelDto.setFileTypeName(null == dictMap.get(trdOrderFileRelDto.getType().toString()) ? null : dictMap.get(trdOrderFileRelDto.getType().toString()).getName());
                SysFile file = fileMap.get(trdOrderFileRelDto.getFileId());
                if (null != file) {
                    trdOrderFileRelDto.setFileUrl(file.getFileLocation());
                    trdOrderFileRelDto.setFileType(file.getContentType());
                    trdOrderFileRelDto.setFileRandomName(file.getFileName());
                }
            }
        }
        return new QResultDto(trdOrderFileRelDtos, pd.getPagination());
    }

}
